package com.siecom.algorithm.des;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;

public class AlgorithmUtil {
    private final static String TRANSFORMATION = "DES/ECB/NoPadding";//DES是加密方式 CBC是工作模式 PKCS5Padding是填充模式
    private final static String IVPARAMETERSPEC = "01020304"; //初始化向量参数，AES 为16bytes. DES 为8bytes.
    private final static String ALGORITHM = "DES";//DES是加密方式
    private static final String SHA1PRNG = "SHA1PRNG"; // SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法

    //3DES
    private static final String KEY_ALGORITHM_3DES = "DESede";
    private static final String CIPHER_ALGORIGHM_3DES = "DESede/ECB/NoPadding";

    public static byte[] encrypt(byte[] key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);

            cipher.init(Cipher.ENCRYPT_MODE, getRawKey(key));
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 对密钥进行处理
    private static Key getRawKey(byte[] key) throws Exception {
        DESKeySpec dks = new DESKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        return keyFactory.generateSecret(dks);
    }

    public static byte[] decrypt(byte[] key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, getRawKey(key));
            return cipher.doFinal(data);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 3DES加(解)密
     *
     * @param data 加(解)密数据
     * @param key  密钥
     * @param mode 类型：加密 {@link Cipher#ENCRYPT_MODE } 1
     *             解密{@link Cipher#DECRYPT_MODE} 2
     * @return 加(解)密后数据
     */
    public static byte[] algorithm3DES(int mode, byte[] key, byte[] data) {

        byte[] tmpKey = new byte[24];
        System.arraycopy(key, 0, tmpKey, 0, 8);
        if (key.length == 16 || key.length == 24) {//分双倍长和三倍长
            System.arraycopy(key, 8, tmpKey, 8, 8);
        } else {
            System.arraycopy(key, 0, tmpKey, 8, 8);
        }
        if (key.length == 24) {
            System.arraycopy(key, 16, tmpKey, 16, 8);
        } else {
            System.arraycopy(key, 0, tmpKey, 16, 8);
        }

        try {
            DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(tmpKey);
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM_3DES);
            SecretKey secretKey = secretKeyFactory.generateSecret(deSedeKeySpec);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORIGHM_3DES);
            cipher.init(mode, secretKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
